#pragma once

#include <unordered_map>
#include <memory>
#include <netinet/in.h>
#include <string>
#include <mutex>

#include "TcpConnection.hpp"
#include "Acceptor.hpp"
#include "EventLoopThreadPool.hpp"

class EventLoop;

class TcpServer {
public:
    TcpServer(EventLoop* loop, const sockaddr_in& listenAddr, int numThreads = 0);
    ~TcpServer();

    void start();  // 启动服务

    void setConnectionCallback(const TcpConnection::ConnectionCallback& cb) { connectionCallback_ = cb; }
    void setMessageCallback(const TcpConnection::MessageCallback& cb)       { messageCallback_ = cb; }

    void setThreadNum(int numThreads) { threadNum_ = numThreads; }

private:
    void newConnection(int sockfd, const sockaddr_in& peerAddr);
    void removeConnection(const TcpConnection::TcpConnectionPtr& conn);

    EventLoop* loop_;
    std::unique_ptr<Acceptor> acceptor_;

    TcpConnection::ConnectionCallback connectionCallback_;
    TcpConnection::MessageCallback messageCallback_;

    int nextConnId_ = 1;
    std::unordered_map<std::string, TcpConnection::TcpConnectionPtr> connections_;

    std::unique_ptr<EventLoopThreadPool> threadPool_;
    int threadNum_;
    std::mutex m;
};
